Conversation
…kargs
Add a new `bootc loader-entries set-options-for-source` command that
manages kernel arguments from independent sources (e.g. TuneD, admin)
by tracking ownership via `x-options-source-<name>` extension keys in
BLS config files. This solves the problem of karg accumulation on bootc
systems with transient /etc, where tools like TuneD lose their state
files on reboot and can't track which kargs they previously set.
The command stages a new deployment with the updated kargs and source
keys. The kargs diff is computed by removing the old source's args and
adding the new ones, preserving all untracked options. Source keys
survive the staging roundtrip via ostree's `bootconfig-extra`
serialization (ostree >= 2026.1, version check present but commented
out until release).
Staged deployment handling:
- No staged deployment: stages based on the booted commit
- Staged deployment exists (e.g. from `bootc upgrade`): replaces it
using the staged commit and origin, preserving pending upgrades while
layering the source kargs change on top
Example usage:
bootc loader-entries set-options-for-source --source tuned \
--options "isolcpus=1-3 nohz_full=1-3"
See: ostreedev/ostree#3570
See: bootc-dev#899
Assisted-by: OpenCode (Claude claude-opus-4-6)
…urce Add a multi-reboot integration test covering the full lifecycle of source-tracked kernel arguments: - Input validation (invalid/empty source names, special characters) - Adding source-tracked kargs and verifying /proc/cmdline after reboot - x-options-source-* BLS keys surviving the staging roundtrip - Source replacement semantics (old kargs removed, new ones added) - Multiple sources coexisting independently - Source removal (--source without --options clears owned kargs) - Idempotent operation (no deployment staged when kargs unchanged) The test uses 4 reboots across 5 phases, matching the same scenarios as the rpm-ostree kolainst test but adapted for the bootc CLI and TMT test framework. Also includes auto-generated man pages for the new loader-entries subcommand. Assisted-by: OpenCode (Claude claude-opus-4-6)
|
Draft while I continue testing. |
There was a problem hiding this comment.
Code Review
This pull request introduces the loader-entries subcommand to manage kernel arguments from multiple independent sources by tracking them via extension keys in BLS configuration files. The implementation includes logic for merging source-specific options and staging new deployments. Review feedback identifies a logic gap in source discovery for staged deployments that could lead to incorrect merging or duplicate arguments, and also recommends replacing blocking synchronous I/O with asynchronous alternatives to prevent performance issues within the async executor.
| for (name, _) in &booted_sources { | ||
| let key = format!("{OPTIONS_SOURCE_KEY_PREFIX}{name}"); | ||
| if let Some(val) = bootconfig.get(&key) { | ||
| sources.insert(name.clone(), CmdlineOwned::from(val.to_string())); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The discovery logic for source keys in staged deployments is incomplete. It only iterates over source names found in the booted BLS entry. If a new source was added in a previous staged deployment (but not yet booted), it won't be discovered here, even if it exists in the staged bootconfig. This can lead to incorrect merging or duplicate kernel arguments. You should explicitly check for the target_source in the bootconfig even if it's not in booted_sources.
if let Ok(bls_content) = read_bls_entry_for_deployment(sysroot, &booted) {
let booted_sources = extract_source_options_from_bls(&bls_content);
for (name, _) in &booted_sources {
let key = format!("{OPTIONS_SOURCE_KEY_PREFIX}{name}");
if let Some(val) = bootconfig.get(&key) {
sources.insert(name.clone(), CmdlineOwned::from(val.to_string()));
}
}
}
// Ensure the target source is also discovered if it exists in the staged bootconfig
let target_key = format!("{OPTIONS_SOURCE_SOURCE_KEY_PREFIX}{source}");
if let Some(val) = bootconfig.get(&target_key) {
sources.insert(source.to_string(), CmdlineOwned::from(val.to_string()));
}| for entry in std::fs::read_dir(&entries_dir) | ||
| .with_context(|| format!("Reading {}", entries_dir.display()))? | ||
| { |
There was a problem hiding this comment.
This function performs blocking synchronous I/O (std::fs::read_dir) within an asynchronous context (it is called by run_from_opt which is async). In a tokio environment, blocking the executor can lead to performance issues. Consider using tokio::fs or wrapping the blocking calls in tokio::task::spawn_blocking.
Add a new
bootc loader-entries set-options-for-sourcecommand thatmanages kernel arguments from independent sources (e.g. TuneD, admin)
by tracking ownership via
x-options-source-<name>extension keys inBLS config files. This solves the problem of karg accumulation on bootc
systems with transient /etc, where tools like TuneD lose their state
files on reboot and can't track which kargs they previously set.
The command stages a new deployment with the updated kargs and source
keys. The kargs diff is computed by removing the old source's args and
adding the new ones, preserving all untracked options. Source keys
survive the staging roundtrip via ostree's
bootconfig-extraserialization (ostree >= 2026.1, version check present but commented
out until release).
Staged deployment handling:
bootc upgrade): replaces itusing the staged commit and origin, preserving pending upgrades while
layering the source kargs change on top
Example usage:
bootc loader-entries set-options-for-source --source tuned
--options "isolcpus=1-3 nohz_full=1-3"
See: ostreedev/ostree#3570